"""
投诉类型分析服务
基于投诉类型进行信访数据的分类统计和趋势分析
"""
from typing import Dict, Any, List, Optional
from datetime import datetime
from sqlalchemy.orm import Session
from sqlalchemy import func, desc, and_
import json

from .base_analyzer import BaseAnalyzer, AnalysisFilters, AnalysisResult
from models.petition_record import ComplaintTypeAnalysisResult
from models.analysis_task import AnalysisTask
from core.logging_config import get_logger

# 日志记录器
logger = get_logger("complaint_analyzer")


class ComplaintAnalysisFilters(AnalysisFilters):
    """投诉类型分析过滤器"""

    def __init__(self):
        super().__init__()
        self.type_level: Optional[str] = None  # 类型级别: level1, level2, level3
        self.complaint_type: Optional[str] = None  # 特定投诉类型
        self.min_confidence: Optional[float] = None  # 最小置信度
        self.confidence_range: Optional[tuple] = None  # 置信度范围


class ComplaintAnalyzer(BaseAnalyzer):
    """投诉类型分析器"""

    def get_model_class(self):
        """获取数据模型类"""
        return ComplaintTypeAnalysisResult

    def analyze_data(self, filters: ComplaintAnalysisFilters) -> AnalysisResult:
        """分析投诉类型数据"""
        try:
            # 构建查询
            query = self.build_base_query(filters)

            # 应用特殊筛选
            if filters.complaint_type:
                query = self._apply_complaint_type_filter(query, filters.complaint_type)

            if filters.min_confidence is not None:
                query = self._apply_confidence_filter(query, filters.min_confidence)

            # 获取基础统计
            basic_stats = self.get_basic_statistics(filters)

            # 获取类型分布
            type_distribution = self.get_type_distribution(query, filters)

            # 获取层级分析
            hierarchy_analysis = self.get_hierarchy_analysis(query, filters)

            # 获取置信度分析
            confidence_analysis = self.get_confidence_analysis(query, filters)

            # 获取时间趋势
            time_series = self.get_time_series_data(filters, 'day')

            # 获取热门类型
            popular_types = self.get_popular_types(query, filters)

            # 组装结果
            result_data = {
                "basic_statistics": basic_stats,
                "type_distribution": type_distribution,
                "hierarchy_analysis": hierarchy_analysis,
                "confidence_analysis": confidence_analysis,
                "time_series": time_series,
                "popular_types": popular_types,
                "analysis_metadata": {
                    "total_records": query.count(),
                    "unique_types": len(type_distribution.get('types', [])),
                    "average_confidence": confidence_analysis.get('average_confidence', 0),
                    "analysis_time": datetime.now().isoformat()
                }
            }

            return AnalysisResult(
                success=True,
                data=result_data,
                message="投诉类型分析完成"
            )

        except Exception as e:
            logger.error(f"投诉类型分析失败: {str(e)}")
            return AnalysisResult(
                success=False,
                data=None,
                message=f"投诉类型分析失败: {str(e)}"
            )

    def get_type_distribution(self, query, filters: ComplaintAnalysisFilters) -> Dict[str, Any]:
        """获取类型分布统计"""
        # 根据类型级别选择字段
        if filters.type_level == 'level1':
            type_field = ComplaintTypeAnalysisResult.tslx_yj
        elif filters.type_level == 'level2':
            type_field = ComplaintTypeAnalysisResult.tslx_ej
        elif filters.type_level == 'level3':
            type_field = ComplaintTypeAnalysisResult.tslx_sj
        else:
            # 默认使用二级类型
            type_field = ComplaintTypeAnalysisResult.tslx_ej

        results = query.with_entities(
            type_field.label('type'),
            func.count().label('count')
        ).filter(type_field.isnot(None), type_field != '').group_by(
            type_field
        ).order_by(desc('count')).limit(15).all()

        types = []
        counts = []

        for result in results:
            if result.type:  # 过滤空值
                types.append(result.type)
                counts.append(result.count)

        return {
            "types": types,
            "counts": counts,
            "total_types": len(types),
            "most_common_type": types[0] if types else None,
            "type_distribution_percentage": self._calculate_percentage(counts)
        }

    def get_hierarchy_analysis(self, query, filters: ComplaintAnalysisFilters) -> Dict[str, Any]:
        """获取层级分析数据"""
        # 获取一级类型分布
        level1_results = query.with_entities(
            ComplaintTypeAnalysisResult.tslx_yj.label('level1'),
            func.count().label('count')
        ).filter(
            ComplaintTypeAnalysisResult.tslx_yj.isnot(None),
            ComplaintTypeAnalysisResult.tslx_yj != ''
        ).group_by(ComplaintTypeAnalysisResult.tslx_yj).order_by(
            desc('count')
        ).all()

        # 构建层级结构
        hierarchy = []
        for level1_result in level1_results:
            if not level1_result.level1:
                continue

            level1_node = {
                "name": level1_result.level1,
                "value": level1_result.count,
                "children": []
            }

            # 获取对应的二级类型
            level2_results = query.with_entities(
                ComplaintTypeAnalysisResult.tslx_ej.label('level2'),
                func.count().label('count')
            ).filter(
                ComplaintTypeAnalysisResult.tslx_yj == level1_result.level1,
                ComplaintTypeAnalysisResult.tslx_ej.isnot(None),
                ComplaintTypeAnalysisResult.tslx_ej != ''
            ).group_by(ComplaintTypeAnalysisResult.tslx_ej).order_by(
                desc('count')
            ).all()

            for level2_result in level2_results:
                if level2_result.level2:
                    level1_node["children"].append({
                        "name": level2_result.level2,
                        "value": level2_result.count
                    })

            hierarchy.append(level1_node)

        return {
            "hierarchy": hierarchy,
            "total_levels": len(hierarchy),
            "max_depth": max(len(node["children"]) for node in hierarchy) if hierarchy else 0
        }

    def get_confidence_analysis(self, query, filters: ComplaintAnalysisFilters) -> Dict[str, Any]:
        """获取置信度分析"""
        confidence_scores = []

        for result in query.all():
            try:
                confidence = result.get_confidence_score()
                confidence_scores.append(confidence)
            except Exception:
                continue

        if not confidence_scores:
            return {
                "average_confidence": 0,
                "min_confidence": 0,
                "max_confidence": 0,
                "distribution": {}
            }

        # 计算统计指标
        avg_confidence = sum(confidence_scores) / len(confidence_scores)
        min_confidence = min(confidence_scores)
        max_confidence = max(confidence_scores)

        # 置信度分布
        distribution = {
            "高置信度 (0.8-1.0)": 0,
            "中置信度 (0.6-0.8)": 0,
            "低置信度 (0.4-0.6)": 0,
            "很低置信度 (0-0.4)": 0
        }

        for score in confidence_scores:
            if score >= 0.8:
                distribution["高置信度 (0.8-1.0)"] += 1
            elif score >= 0.6:
                distribution["中置信度 (0.6-0.8)"] += 1
            elif score >= 0.4:
                distribution["低置信度 (0.4-0.6)"] += 1
            else:
                distribution["很低置信度 (0-0.4)"] += 1

        # 转换为百分比
        total = len(confidence_scores)
        distribution_percentage = {
            k: round((v / total) * 100, 2) for k, v in distribution.items()
        }

        return {
            "average_confidence": round(avg_confidence, 3),
            "min_confidence": round(min_confidence, 3),
            "max_confidence": round(max_confidence, 3),
            "distribution": distribution,
            "distribution_percentage": distribution_percentage,
            "total_samples": total
        }

    def get_popular_types(self, query, filters: ComplaintAnalysisFilters, limit: int = 10) -> List[Dict[str, Any]]:
        """获取热门类型"""
        # 使用二级类型进行统计
        results = query.with_entities(
            ComplaintTypeAnalysisResult.tslx_ej.label('type'),
            ComplaintTypeAnalysisResult.tslx_sj.label('subtype'),
            func.count().label('count'),
            func.avg(
                func.cast(
                    func.replace(ComplaintTypeAnalysisResult.tslx_ej_zxd, '%', ''),
                    float
                ) / 100
            ).label('avg_confidence')
        ).filter(
            ComplaintTypeAnalysisResult.tslx_ej.isnot(None),
            ComplaintTypeAnalysisResult.tslx_ej != ''
        ).group_by(
            ComplaintTypeAnalysisResult.tslx_ej,
            ComplaintTypeAnalysisResult.tslx_sj
        ).order_by(desc('count')).limit(limit).all()

        popular_types = []
        for result in results:
            if result.type:
                avg_conf = result.avg_confidence or 0.5
                popular_types.append({
                    "type": result.type,
                    "subtype": result.subtype or "未细分",
                    "count": result.count,
                    "percentage": round((result.count / query.count()) * 100, 2) if query.count() > 0 else 0,
                    "average_confidence": round(avg_confidence, 3)
                })

        return popular_types

    def _apply_complaint_type_filter(self, query, complaint_type: str):
        """应用投诉类型筛选"""
        return query.filter(
            or_(
                ComplaintTypeAnalysisResult.tslx_yj == complaint_type,
                ComplaintTypeAnalysisResult.tslx_ej == complaint_type,
                ComplaintTypeAnalysisResult.tslx_sj == complaint_type
            )
        )

    def _apply_confidence_filter(self, query, min_confidence: float):
        """应用置信度筛选"""
        # 需要根据实际的置信度字段进行调整
        return query  # 简化实现

    def _calculate_percentage(self, counts: List[int]) -> List[float]:
        """计算百分比"""
        if not counts:
            return []

        total = sum(counts)
        if total == 0:
            return [0.0] * len(counts)

        return [round((count / total) * 100, 2) for count in counts]

    def get_type_trends(self, complaint_type: str, filters: ComplaintAnalysisFilters) -> Dict[str, Any]:
        """获取特定类型的时间趋势"""
        query = self.build_base_query(filters)
        type_query = self._apply_complaint_type_filter(query, complaint_type)

        # 按日期统计
        daily_stats = type_query.with_entities(
            func.date(ComplaintTypeAnalysisResult.created_at).label('date'),
            func.count().label('count')
        ).group_by(
            func.date(ComplaintTypeAnalysisResult.created_at)
        ).order_by('date').all()

        return {
            "type": complaint_type,
            "daily_trends": [
                {
                    "date": stat.date.isoformat(),
                    "count": stat.count
                }
                for stat in daily_stats
            ]
        }

    def get_type_comparison(self, type_list: List[str], filters: ComplaintAnalysisFilters) -> Dict[str, Any]:
        """获取多个类型的对比分析"""
        comparison_data = {}

        for complaint_type in type_list:
            type_query = self._apply_complaint_type_filter(self.build_base_query(filters), complaint_type)
            count = type_query.count()

            comparison_data[complaint_type] = {
                "count": count,
                "percentage": round((count / self.build_base_query(filters).count()) * 100, 2) if self.build_base_query(filters).count() > 0 else 0
            }

        return comparison_data